
#include <p18f4550.h>
#include "GenericTypeDefs.h"

#include "HardwareProfile.h"
#include "Fpga.h"


/** V A R I A B L E S ********************************************************/
#pragma udata

WORD_VAL mRamAddr;
DWORD_VAL wfreq;
WORD_VAL wphase;
/** P R I V A T E   P R O T O T Y P E S **************************************/

#pragma code


void InitFpga(void)
{

	// Initialize Fpga
	mInitFpga();

}

/*void ManualClk()
{
    int j;
//	fpga_manclk = 1;					// cycle clock
	// inverse clock cycle
	fpga_manclk = 0;

        for (j = 0; j < 10; j++)
	{
			;
	}

	fpga_manclk = 1;				
}*/

/*void WriteClk()
{
    int j;
	fpga_writeclk = 1;					// cycle clock
       for (j = 0; j < 10; j++)
	{
			;
	}
	fpga_writeclk = 0;
}*/

void FpgaReset()
{
	fpga_clksel = 1;
	fpga_reset = 1;						// Set reset to 1
	fpga_manclk = 1;					// cycle clock to validate reset
	fpga_manclk = 0;
	fpga_manclk = 1;
	fpga_manclk = 0;
	fpga_manclk = 1;
	fpga_manclk = 0;
	fpga_manclk = 1;
	fpga_reset = 0;
}

void FpgaResetStop()
{
	FpgaReset();

	// set fpga read
	mSetFpgaAddr(0x0a);
	fpga_data = 0x00;
	WriteClk();

	// set ram reset
	mSetFpgaAddr(0x09);
	fpga_data = 0xff;
	WriteClk();

	ManualClk();
	ManualClk();
}

void FpgaInitWrite()
{
	// reset ram reset
	mSetFpgaAddr(0x09);
	fpga_data = 0x00;
	WriteClk();
	
	// set fpga write
	mSetFpgaAddr(0x0a);
	fpga_data = 0xff;
	WriteClk();

	mRamAddr.Val = 0;

	ManualClk();
	ManualClk();
}

void FpgaWrite(BYTE* data, SHORT size)
{
	SHORT i = 0;
	SHORT j = 0;
	while(i < size)
	{
		// reset clk
		mSetFpgaAddr(0x0c);
		fpga_data = 0x00;
		WriteClk();

		// set address
		mSetFpgaAddr(0x06);
		fpga_data = mRamAddr.byte.LB;
		WriteClk();
		mSetFpgaAddr(0x07);
		fpga_data = mRamAddr.byte.HB;
		WriteClk();
		WriteClk();

		// set data
		mSetFpgaAddr(0x08);
		fpga_data = data[i];
		WriteClk();

		// set clk
		mSetFpgaAddr(0x0c);
		fpga_data = 0xff;
		WriteClk();

		// nop
		// TODO: Kell ez ide?
		/*for (j = 0; j < 10; j++)
		{
			;
		}*/

		i++;
		mRamAddr.Val++;
	}
}

void FpgaInitGenerate(DWORD freq, SHORT phase, BYTE manualclk)
{
	// reset ram reset
	mSetFpgaAddr(0x09);
	fpga_data = 0x00;
	WriteClk();
	
	// set fpga read
	mSetFpgaAddr(0x0a);
	fpga_data = 0x00;
	WriteClk();

	FpgaSetFreq(freq);
	FpgaSetPhase(phase);

	FpgaReset();

	//fpga_clksel = 0;
	FpgaSetClockSource(manualclk);
	fpga_manclk = 0;	// ez kell hogy a clock valtas menjen
	fpga_manclk = 1;
}

void FpgaSetFreq(DWORD freq)
{
	// TODO: ez lehetne szebb is
    wfreq.Val = freq;
	mSetFpgaAddr(0x00);
	fpga_data = wfreq.byte.LB;
	WriteClk();
	mSetFpgaAddr(0x01);
	fpga_data = wfreq.byte.HB;
	WriteClk();
	mSetFpgaAddr(0x02);
	fpga_data = wfreq.byte.UB;
	WriteClk();
	mSetFpgaAddr(0x03);
	fpga_data = wfreq.byte.MB;
	WriteClk();
	WriteClk();
}

void FpgaSetPhase(SHORT phase)
{
	// TODO: ez is
    wphase.Val = phase;
	mSetFpgaAddr(0x04);
	fpga_data = wphase.byte.LB;
	WriteClk();
	mSetFpgaAddr(0x05);
	fpga_data = wphase.byte.HB;
	WriteClk();
	WriteClk();
}

void FpgaSetClockSource(BYTE manual)
{
	if (manual == 1)
		fpga_clksel = 1;
	else
		fpga_clksel = 0;
}
